<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>H5转盘抽奖</title>
</head>
<style>
	body {
		font-family: "微软雅黑", Helvetica, Arial, sans-serif;
		font-size: 16px;
	}

	.wrapper {
		width: 620px;
		margin: 20px auto;
	}

	input {
		float: left;
		padding: 5px;
		font-size: 20px;
		border-radius: 6px;
		border: none;
		outline: none;
		cursor: pointer;
	}

	input:hover {
		background-color: #00b7e9;
	}
</style>
<body>
<div class="wrapper">
	<input type="button" value="开始旋转" onclick="spin();">
	<canvas id="wheel_canvas" width="500" height="500"></canvas>
</div>
<script>
  let colors = ["#B8D430", "#3AB745", "#029990", "#3501CB", "#2E2C75", "#673A7E", "#CC0071", "#F80120", "#F35B20", "#FB9A00", "#FFCC00", "#FEF200"];
  let cities = ["北京", "上海", "天津", "南京", "杭州", "深圳", "武汉", "济南", "重庆", "大连", "合肥", "郑洲"];
  let startAngle = 0;
  let arc = Math.PI / 6;
  let spinTimeout = null;
  let spinTime = 0;
  let spinTimeTotal = 0;
  let ctx;

  function draw() {
    drawRouletteWheel();
  }

  function drawRouletteWheel() {
    let canvas = document.getElementById('wheel_canvas');
    if (canvas.getContext) {
      let outsideRadius = 200;
      let textRadius = 160;
      let insideRadius = 125;
      ctx = canvas.getContext("2d");
      ctx.clearRect(0, 0, 500, 500);
      ctx.strokeStyle = 'black';
      ctx.lineWidth = 2;
      ctx.font = 'bold 16px sans-serif';
      for (let i = 0; i < 12; i++) {
        let angle = startAngle + i * arc;
        ctx.fillStyle = colors[i];
        ctx.beginPath();
        ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
        ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
        ctx.stroke();
        ctx.fill();
        ctx.save();
        ctx.shadowOffsetX = 1;
        ctx.shadowOffsetY = -1;
        ctx.shadowBlur = 0;
        ctx.shadowColor = "rgb(220,220,220)";
        ctx.fillStyle = 'black';
        ctx.translate(250 + Math.cos(angle + arc / 2) * textRadius, 250 + Math.sin(angle + arc / 2) * textRadius);
        ctx.rotate(angle + arc / 2 + Math.PI / 2);
        let text = cities[i];
        ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
        ctx.restore();
      }
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
      ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
      ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
      ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
      ctx.lineTo(250, 250 - (outsideRadius - 13));
      ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
      ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
      ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
      ctx.fill();
    }
  }

  function spin() {
    spinAngleStart = Math.random() * 10 + 10;
    spinTime = 0;
    spinTimeTotal = Math.random() * 3 + 4 * 1000;
    rotateWheel();
  }

  function rotateWheel() {
    spinTime += 30;
    if (spinTime >= spinTimeTotal) {
      stopRotateWheel();
      return;
    }
    let spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
    startAngle += (spinAngle * Math.PI / 180);
    drawRouletteWheel();
    spinTimeout = setTimeout('rotateWheel()', 30)
  }

  function stopRotateWheel() {
    clearTimeout(spinTimeout);
    let degrees = startAngle * 180 / Math.PI + 90;
    let arcd = arc * 180 / Math.PI;
    let index = Math.floor((360 - degrees % 360) / arcd);
    ctx.save();
    ctx.font = 'bold 30px sans-serif';
    let text = cities[index];
    ctx.fillText(text, 250 - ctx.measureText(text).width / 2, 250 + 10);
    ctx.restore();
  }

  function easeOut(t, b, c, d) {
    let ts = (t /= d) * t;
    let tc = ts * t;
    return b + c * (tc + (-3 * ts) + 3 * t);
  }

  draw();
</script>
</body>
</html>